今天將會是密碼學最後一個常見的主題:亂數。
亂數的隨機性有三個參考標準:
依上述三個標準會有三種隨機數產生器
在一般應用上,偽隨機數就夠用了。但如果要考慮到安全議題的話,只能選擇密碼學安全的僞隨機數或真隨機數。像產生臨時金鑰即會用亂數,若亂數可被攻擊者推測的話,代表金鑰內容能被攻擊者推測出來,所有密碼防護功能就會完全沒有意義。
亂數在身分驗證上,應用場景非常多,除了剛剛提到的臨時金鑰外,像一次性密碼(OTP)、CBC 的初始向量、CSRF Token、Session Identifier 等,非常多場景會需要用到亂數產生器,因此亂數有沒有密碼學安全是非常重要。
參考維基百科上的資料,蠻多對筆者而言都很難理解,因此最終選擇了一個最好懂的來說明。
RSA 加密演算法的核心原理是兩個極大的質數相乘容易,分解困難的性質來設計的,而公鑰的設計則是可以安心的對外散佈。今天有兩把公鑰分別是 n = pq 與 n' = p'q'。若偽隨機數產生的質數剛好發生 p = p',這時想從 n 與 n' 拆出 p 是非常容易的--使用輾轉相除法取因數即可,這時要再拿 q 或 q' 就不是問題了。
RSA 是個很簡單的例子,讓大家可以理解偽隨機數會有安全性上的問題。所以安全上若有考量,則一定得使用 CSPRNG。
在 PHP 5 之前,只有 PRNG,直到 PHP 7 開始才有 CSPRNG,裡面包含了兩個函式:random_bytes()
與 random_int()
。
而 PHP 5 可以使用 openssl_random_pseudo_bytes()
或是使用 paragonie/random_compat
這個套件做 polyfill。
密碼學的介紹到此告一段落,因筆者對此領域不熟,每天的內容都少的可憐,有機會要來好好補充這個領域的知識了。